﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AvaliacaoOnline.Data;
using System.Data;

namespace AvaliacaoOnline.Model
{
    public class UsuarioRepository
    {
        public Usuario GetUsuario(int idUsuario)
        {
            AvaliacaoOnlineContext context = AvaliacaoOnlineContext.GetContext();

            return context.Usuario.Where(c => c.Id == idUsuario).FirstOrDefault();
        }

        public List<Usuario> GetUsuarios(int idCliente)
        {
            AvaliacaoOnlineContext context = AvaliacaoOnlineContext.GetContext();

            return context.Usuario.Where(c => c.IdCliente == idCliente).ToList();
        }

        public List<Usuario> GetUsuarios(int idCliente, int idAvaliacao)
        {
            AvaliacaoOnlineContext context = AvaliacaoOnlineContext.GetContext();

            return (from u in context.Usuario.Include("AvaliacaoUsuario")
                    join a in context.AvaliacaoUsuario
                    on u.Id equals a.IdUsuario
                    where a.IdAvaliacao == idAvaliacao &&
                          u.IdCliente == idCliente
                    select u).ToList();
        }

        public List<GrupoUsuario> GetGruposUsuario()
        {
            AvaliacaoOnlineContext context = AvaliacaoOnlineContext.GetContext();

            return context.GrupoUsuario.ToList();
        }

        public void GravarUsuario(Usuario usuario, ref string erros)
        {
            AvaliacaoOnlineContext context = AvaliacaoOnlineContext.GetContext();

            List<String> lstErros = ValidaUsuario(usuario).ToList();
            if (lstErros.Count > 0)
            {
                foreach (string s in lstErros)
                    erros += s + Environment.NewLine;

                return;
            }

            int qdteLogin = context.Usuario.Where(c => c.Login == usuario.Login && c.Id != usuario.Id).Count();
            if (qdteLogin >= 1)
                erros += "Login já existe.";

            if (usuario.Id == 0)
            {
                context.Usuario.AddObject(usuario);
            }
            else
            {
                context.Usuario.Attach(usuario);
                context.ObjectStateManager.ChangeObjectState(usuario, EntityState.Modified);
            }
            context.SaveChanges();
        }

        public void ExcluirUsuario(int idUsuario, ref string erros)
        {
            AvaliacaoOnlineContext context = AvaliacaoOnlineContext.GetContext();

            if (context.AvaliacaoUsuario
                .Where(c => c.IdUsuario == idUsuario && c.DataInicial != null).Count() > 0)
            {
                erros = "Este usuário já participou de uma avaliação e não pode ser excluído.";
                return;
            }

            var lstAvaliacaoUsuario = context.AvaliacaoUsuario.Where(c => c.IdUsuario == idUsuario).ToList();

            foreach (AvaliacaoUsuario item in lstAvaliacaoUsuario)
                context.DeleteObject(item);

            context.DeleteObject(context.Usuario.Where(c => c.Id == idUsuario).First());

            context.SaveChanges();
        }

        public void RemoverUsuarioAvaliacao(int idCliente, int idUsuario, int idAvaliacao, ref string erros)
        {
            AvaliacaoOnlineContext context = AvaliacaoOnlineContext.GetContext();

            if (context.AvaliacaoUsuario
                .Where(c => c.IdUsuario == idUsuario && c.IdAvaliacao == idAvaliacao && c.DataInicial != null).Count() > 0)
            {
                erros = "Este usuário já participou da avaliação em questão e não pode ser removido dela.";
                return;
            }

            var lstAvaliacaoUsuario = context.AvaliacaoUsuario.Where(c => c.IdUsuario == idUsuario && c.IdAvaliacao == idAvaliacao).ToList();

            foreach (AvaliacaoUsuario item in lstAvaliacaoUsuario)
                context.DeleteObject(item);

            context.SaveChanges();
        }

        public string GravarUsuarios(int idCliente, int idAvaliacao, List<UsuarioModelo> lstUsuarios)
        {
            AvaliacaoOnlineContext context = AvaliacaoOnlineContext.GetContext();
            StringBuilder builder = new StringBuilder();

            foreach (UsuarioModelo item in lstUsuarios)
            {
                Usuario usuario = new Usuario();
                usuario.IdCliente = idCliente;
                usuario.Email = item.Email;
                usuario.Login = item.Login;
                usuario.Nome = item.Nome;
                usuario.Senha = item.Senha;
                usuario.Tipo = item.Tipo.ToUpper();

                List<GrupoUsuario> lstGrupo = GetGruposUsuario();
                if (lstGrupo.Where(c => c.Descricao.ToUpper() == item.Grupo.ToUpper()).Count() > 0)
                {
                    usuario.IdGrupoUsuario = lstGrupo.Where(c => c.Descricao.ToUpper() == item.Grupo.ToUpper()).First().Id;
                }
                else
                {
                    builder.AppendLine("Grupo de usuário [" + item.Grupo + "] não encontrado.");
                    continue;
                }

                Usuario usuarioCadastrado = context.Usuario.Where(c => c.IdCliente == idCliente && c.Login.ToLower() == item.Login.ToLower()).FirstOrDefault();
                if (usuarioCadastrado != null)
                {
                    builder.AppendLine("Usuário login [" + item.Login + "] já existe.");
                    if (context.AvaliacaoUsuario.Where(c => c.IdUsuario == usuarioCadastrado.Id && c.IdAvaliacao == idAvaliacao).Count() > 0)
                    {
                        builder.AppendLine("Usuário login [" + item.Login + "] já está vinculado à avaliação.");
                    }
                    else
                    {
                        context.AvaliacaoUsuario.AddObject(new AvaliacaoUsuario()
                        {
                            IdAvaliacao = idAvaliacao,
                            IdUsuario = usuarioCadastrado.Id,
                            Concluido = "N"
                        });
                        builder.AppendLine("Usuário login [" + item.Login + "] vinculado à avaliação com sucesso.");
                    }
                }
                else
                {
                    usuario.AvaliacoesUsuario.Add(new AvaliacaoUsuario()
                    {
                        IdAvaliacao = idAvaliacao,
                        Concluido = "N"
                    });

                    context.Usuario.AddObject(usuario);
                    builder.AppendLine("Usuário login [" + item.Login + "] inserido com sucesso.");
                    builder.AppendLine("Usuário login [" + item.Login + "] vinculado à avaliação com sucesso.");
                }
            }

            context.SaveChanges();
            return builder.ToString();
        }

        public void InserirUsuarioAvaliacao(int idUsuario, int idAvaliacao)
        {
            AvaliacaoOnlineContext context = AvaliacaoOnlineContext.GetContext();
            if (context.AvaliacaoUsuario.Where(c => c.IdUsuario == idUsuario && c.IdAvaliacao == idAvaliacao).Count() == 0)
            {
                context.AvaliacaoUsuario.AddObject(new AvaliacaoUsuario()
                {
                    IdAvaliacao = idAvaliacao,
                    IdUsuario = idUsuario,
                    Concluido = "N"
                });
            }
            context.SaveChanges();
        }

        public IEnumerable<String> ValidaUsuario(Usuario usuario)
        {
            if (String.IsNullOrWhiteSpace(usuario.Nome))
                yield return "O campo nome não pode ser vazio.";
            if (String.IsNullOrWhiteSpace(usuario.Login))
                yield return "O campo login não pode ser vazio.";
            if (String.IsNullOrWhiteSpace(usuario.Email))
                yield return "O campo e-mail não pode ser vazio.";
            if (String.IsNullOrWhiteSpace(usuario.Senha))
                yield return "O campo senha não pode ser vazio.";

        }
    }
}
